<template>
  <div ref="container" class="container"></div>
</template>

<script setup>
import { onMounted, onUnmounted, ref } from "vue";
import { Water } from "three/addons/objects/Water.js";
import { Sky } from "three/addons/objects/Sky.js";
import waterNormalsUrl from "@/assets/texture/waternormals.jpg";
import { THREE, OrbitControls, RGBELoader } from "@/scripts/three/toolchain"; // 引入 Three.js 库
import rustyUrl from "@/assets/texture/tex02.jpg";

const rgbeLoader = new RGBELoader();

const container = ref(null);
let camera,
  scene,
  renderer,
  orbitControls,
  water,
  mirrorMesh,
  sky,
  sunSphere,
  light;
let waterNormals, rusty;
const azimuth = 0.45843;
const inclination = 0.3011;
const clock = new THREE.Clock();
let v;

const init = () => {
  // Setup renderer
  renderer = new THREE.WebGLRenderer({ antialias: true });
  renderer.setPixelRatio(window.devicePixelRatio);
  renderer.setSize(window.innerWidth, window.innerHeight);
  renderer.shadowMap.enabled = true;
  renderer.shadowMap.type = THREE.PCFSoftShadowMap;
  container.value.appendChild(renderer.domElement);

  // Setup scene and camera
  scene = new THREE.Scene();
  camera = new THREE.PerspectiveCamera(
    55,
    window.innerWidth / window.innerHeight,
    0.5,
    3000000
  );
  camera.position.set(0, 15, 0);
  camera.rotation.set(-0, 0, 0);

  initSky();
  
  window.addEventListener("resize", onWindowResize);
  const waterGeometry = new THREE.PlaneGeometry(4400, 4400);

  // Water setup

  water = new Water(waterGeometry, {
    textureWidth: 512,
    textureHeight: 512,
    waterNormals,
    alpha: 1.0,
    sunDirection: sky.material.uniforms["sunPosition"].value.normalize(),
    sunColor: 0xf5ebce,
    waterColor: 0x5b899b,
    distortionScale: 15.0,
  });

  mirrorMesh = new THREE.Mesh(
    new THREE.PlaneGeometry(4400, 4400, 120, 120),
    water.material
  );

  mirrorMesh.add(water);
  mirrorMesh.rotation.x = -Math.PI * 0.5;
  scene.add(mirrorMesh);

  v = mirrorMesh.geometry.attributes.position.array;

  // Lighting
  const ambient = new THREE.AmbientLight(0xf5ebce, 0.25);
  scene.add(ambient);

  light = new THREE.DirectionalLight(0xf5ebce, 0.8);
  light.position.set(0, 0, 0);
  light.castShadow = true;

  scene.add(light);
  light.shadow.mapSize.width = 2048; // default
  light.shadow.mapSize.height = 2048; // default

  // Elements
  const n = 110;

  for (let i = n - 1; i >= 0; i--) {
    const elementGeometry = new THREE.CylinderGeometry(
      5,
      5,
      (random(i) + 1) * 50,
      4
    );

    // 🎯 处理 UV 偏移（BufferGeometry）
    const uvAttribute = elementGeometry.attributes.uv;
    const addU = Math.random();
    const addV = Math.random();

    for (let j = 0; j < uvAttribute.count; j++) {
      uvAttribute.setX(j, uvAttribute.getX(j) + addU);
      uvAttribute.setY(j, uvAttribute.getY(j) + addV);
    }

    uvAttribute.needsUpdate = true;

    // 🎨 创建材质
    const elementMaterial = new THREE.MeshPhongMaterial({
      specular: 0xf5ebce,
      shininess: 23,
      specularMap: rusty,
      map: rusty,
      flatShading: true,
    });

    const element = new THREE.Mesh(elementGeometry, elementMaterial);
    scene.add(element);

    // 设置位置
    element.position.set(
      (random(i + 214) - 0.5) * 1500,
      elementGeometry.parameters.height / 2 - 5,
      -random(i * 35) * 1500 - 100
    );

    // 旋转
    element.rotation.set((random(i) * Math.PI) / 20, 0, 0);

    // 阴影
    element.receiveShadow = true;
    element.castShadow = true;
  }
};
const initSky = () => {
  sky = new Sky();

  scene.add(sky);

  sunSphere = new THREE.Mesh(
    new THREE.SphereGeometry(20, 16, 8),
    new THREE.MeshBasicMaterial({ color: 0xffffff })
  );
  sunSphere.visible = true;

  scene.add(sunSphere);

  const uniforms = sky.material.uniforms;

  uniforms["turbidity"].value = 0.01;
  uniforms["rayleigh"].value = 0.0066;
  // uniforms["luminance"].value = 0.8;
  uniforms["mieCoefficient"].value = 10.1;

  uniforms["mieDirectionalG"].value = 0.824;

  moveSun();
};

const moveSun = () => {
  const distance = 4500;

  const theta = Math.PI * (inclination - 0.5);
  const phi = 2 * Math.PI * (azimuth - 0.5);

  sunSphere.position.set(
    distance * Math.cos(phi),
    distance * Math.sin(phi) * Math.sin(theta),
    distance * Math.sin(phi) * Math.cos(theta)
  );

  sky.material.uniforms["sunPosition"].value.copy(sunSphere.position);
};

const random = (seed) => {
  const x = Math.sin(seed) * 10000;
  return x - Math.floor(x);
};

let time = 0;
const animate = () => {
  const delta = clock.getDelta();
  time += delta * 0.5;

  // 获取 position 属性
  const positionAttribute = mirrorMesh.geometry.attributes.position;
  if (!positionAttribute) {
    console.error("position attribute is undefined");
    return;
  }

  const vertices = positionAttribute.array; // Float32Array，包含 x, y, z 坐标
  const vertexCount = positionAttribute.count; // 顶点数量

  // 遍历顶点并修改 z 坐标
  for (let i = vertexCount - 1; i >= 0; i--) {
    const index = i * 3; // 每个顶点有 3 个值 (x, y, z)
    vertices[index + 2] = Math.sin(i * 1 + time * -1) * 3; // 修改 z 坐标
  }
  // 更新 camera 的 y 位置，使用第 7320 个顶点的 z 值
  const vertex7320Index = 7320 * 3; // 第 7320 个顶点的索引
  if (vertex7320Index + 2 < vertices.length) {
    camera.position.y = vertices[vertex7320Index + 2] * 1.5 + 14;
  } else {
    // console.warn("Vertex 7320 is out of bounds");
    camera.position.y = 14; // 默认值
  }

  // 标记需要更新
  positionAttribute.needsUpdate = true;

  moveSun();
  water.material.uniforms["time"].value -= 1.0 / 60.0;
  water.sunDirection = sky.material.uniforms["sunPosition"].value.normalize();
  light.position.copy(sunSphere.position);
  renderer.render(scene, camera);
  requestAnimationFrame(animate);
};

const onWindowResize = () => {
  if (camera) {
    camera.aspect = window.innerWidth / window.innerHeight;
    camera.updateProjectionMatrix();
  }
  renderer.setSize(window.innerWidth, window.innerHeight);
};

onMounted(() => {
  const loader = new THREE.TextureLoader();

  loader.load(waterNormalsUrl, (t) => {
    t.mapping = THREE.UVMapping;
    waterNormals = t;
    waterNormals.wrapS = waterNormals.wrapT = THREE.RepeatWrapping;

    loader.load(rustyUrl, (r) => {
      rusty = r;
      rusty.wrapS = rusty.wrapT = THREE.RepeatWrapping;

      init();
      animate();
      // rgbeLoader.load(
      //   "/texture/overcast_soil_puresky_2k.hdr", // 文件路径
      //   (texture) => {
      //     // 设置纹理编码（HDR 需要特定的编码）
      //     texture.mapping = THREE.EquirectangularReflectionMapping; // 通常用于环境贴图
      //     texture.encoding = THREE.RGBEEncoding; // HDR 编码方式

      //     // 将纹理应用到场景（例如作为背景或环境贴图）
      //     scene.background = texture;
      //     scene.environment = texture; // 用于 PBR 材质的环境光照
      //   },
      //   (progress) => {
      //     // 加载进度
      //   },
      //   (error) => {
      //     // 加载错误
      //     console.error("Error loading HDR texture:", error);
      //   }
      // );
    });
  });

});

onUnmounted(() => {
  window.removeEventListener("resize", onWindowResize);
  if (container.value && renderer.domElement) {
    container.value.removeChild(renderer.domElement);
  }
});
</script>

<style scoped>
.container {
  margin: 0;
  overflow: hidden;
  background-color: #ffffff;
  height: 100%;
  width: 100%;
}
</style>
